package rlyy.framework.core.resolver.argument;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import rlyy.framework.core.common.enums.CommonEnum;
import rlyy.framework.core.common.exception.ParameterParseException;
import rlyy.framework.core.common.request.FullRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestParam;

import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * @author yuanqinglong
 * @since 2020/7/20 17:19
 */
@Component
public class ListMethodArgumentResolver implements MyHandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(Parameter parameter) {
        return parameter != null && List.class.isAssignableFrom(parameter.getType());
    }


    @Override
    public Object resolveArgument(Parameter parameter, FullRequest fullRequest) throws Exception {
        // 仅支持泛型是简单数据类型和实体对象的参数
        JSONObject args = fullRequest.getData();
        if (CollectionUtils.isEmpty(args)) {
            return null;
        }
        RequestParam requestParam = parameter.getAnnotation(RequestParam.class);
        String requestParamName = Optional.ofNullable(requestParam).map(param -> Optional.of(param).map(RequestParam::value).orElseGet(param::name)).orElse(null);
        JSONArray jsonArray = Optional.ofNullable(requestParamName).map(args::getJSONArray).orElseGet(() -> args.getJSONArray(parameter.getName()));
        Boolean required = Optional.ofNullable(requestParam).map(RequestParam::required).orElse(true);
        if (required && ObjectUtils.isEmpty(jsonArray)) {
            throw new ParameterParseException(CommonEnum.PARAMS_NOT_ENOUGH);
        }
        if (!required && ObjectUtils.isEmpty(jsonArray)) {
            return Collections.emptyList();
        }
        Type parameterizedType1 = parameter.getParameterizedType();
        String typeName = parameterizedType1.getTypeName();
        boolean generic = typeName.contains("<") && typeName.contains(">");
        if (!generic) {
            return JSONObject.parseArray(jsonArray.toJSONString());
        }
        //获取泛型路径
        String genericPath = typeName.substring(typeName.indexOf("<") + 1, typeName.lastIndexOf(">"));
        Class<?> aClass = Class.forName(genericPath);
        return jsonArray.toJavaList(aClass);
    }

    @Override
    public int getOrder() {
        return 70;
    }
}
